﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace PSE.Framework.Configuration
{
    public enum SystemComponentType
    { 
        System = 0,
        Component = 1
    }

    [Serializable]
    public struct SystemComponent : IEquatable<SystemComponent>, IComparable, IComparable<SystemComponent>
    {
        public static readonly SystemComponent Empty = new SystemComponent();

        public SystemComponent(string name, string description, SystemComponentType type)
            : this()
        {
            if (string.IsNullOrEmpty(name))
                throw new ArgumentNullException("name");
            if (string.IsNullOrEmpty(description))
                throw new ArgumentNullException("description");

            _name = name;
            _description = description;
            _type = type;
        }

        private string _name;

        public string Name
        {
            get { return _name; }
        }

        private string _description;

        public string Description
        {
            get { return _description; }
        }

        private SystemComponentType? _type;

        public SystemComponentType? Type
        {
            get { return _type; }
        }

        public bool IsEmpty
        {
            get { return this.Name == null && this.Type == null; }
        }

        public override int GetHashCode()
        {
            return string.Format("{0:d}{1}", this.Type, this.Name).GetHashCode();
        }

        public static bool operator ==(SystemComponent a, SystemComponent b)
        {
            return a.Equals(b);
        }

        public static bool operator !=(SystemComponent a, SystemComponent b)
        {
            return !(a == b);
        }

        public override bool Equals(object obj)
        {
            return obj is SystemComponent ? this.Equals((SystemComponent)obj) : false;
        }

        public bool Equals(SystemComponent other)
        {
            return ((this.Name ?? string.Empty) == (other.Name ?? string.Empty)) && (this.Type == other.Type);
        }

        public int CompareTo(object obj)
        {
            if (!(obj is SystemComponent))
                throw new ArgumentException("Parameter is not SystemComponent", "obj");

            return this.CompareTo((SystemComponent)obj);
        }

        public int CompareTo(SystemComponent other)
        {
            return string.Format("{0:d}{1}", this.Type, this.Name).CompareTo(string.Format("{0:d}{1}", other.Type, other.Name));
        }

        public override string ToString()
        {
            return this.Name ?? string.Empty;
        }
    }
}